package me.numark.fragments;

import com.google.gson.Gson;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;

import org.json.JSONObject;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import me.numark.R;
import me.numark.model.Topic;
import me.numark.net.AuthorizedJsonObjectRequest;
import me.numark.net.BaseResponse;
import me.numark.net.GsonRequest;
import me.numark.net.NetworkConstants;
import me.numark.net.NetworkHelper;
import me.numark.utils.LogUtils;
import me.numark.utils.Settings;
import me.numark.view.InterestCheckBox;

/**
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * to handle interaction events.
 * Use the {@link InterestsFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class InterestsFragment extends Fragment
        implements View.OnClickListener, InterestCheckBox.CheckStateChangedListener {

    private RegisterListener mListener;

    private TextView rightButton;

    private GridView interestsGrid;

    private GridView friendsGrid;

    private String[] mFriendsArray;

    private InterestAdapter mInterestAdapter;


    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @return A new instance of fragment InterestsFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static InterestsFragment newInstance() {
        InterestsFragment fragment = new InterestsFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    public InterestsFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_interests, container, false);
        TextView title = (TextView) view.findViewById(R.id.title);
        title.setText(R.string.set_interests);
        mFriendsArray = getResources().getStringArray(R.array.friends_array);
        view.findViewById(R.id.back).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getActivity().finish();
            }
        });
        rightButton = (TextView) view.findViewById(R.id.right_text);
        rightButton.setEnabled(true);
        rightButton.setOnClickListener(this);
        rightButton.setText(R.string.next_step);
        mInterestAdapter = new InterestAdapter();
        interestsGrid = (GridView) view.findViewById(R.id.grid);
        interestsGrid.setAdapter(mInterestAdapter);
        friendsGrid = (GridView) view.findViewById(R.id.grid2);
        friendsGrid.setAdapter(new FriendsAdapter());
        getTopics();
        return view;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (RegisterListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.right_text:
                submitTopics();
                break;
        }
    }

    private void submitTopics() {
        String uid = Settings.getUid();
        String url = String.format(NetworkConstants.REGISTER_FAVORITE_URL, uid);
        Map<String, String> body = new LinkedHashMap<String, String>();
        //TODO: add interest topic parameter
        GsonRequest<BaseResponse> request = new GsonRequest<BaseResponse>(url,
                Request.Method.POST, BaseResponse.class,
                true, null, new Response.Listener<BaseResponse>() {
            @Override
            public void onResponse(BaseResponse response) {
                LogUtils.d("getTopics, response is " + response);
                if (response.ret) {
                    mListener.onNext(InterestsFragment.this, null);
                } else {
                    mListener.onFailure(response.msg);
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                mListener.onFailure(getString(R.string.submit_topics_failed));
            }
        });
        NetworkHelper.getInstance().getRequestQueue().add(request);
        NetworkHelper.getInstance().getRequestQueue().start();
        mListener.onShowProgress(getString(R.string.submitting_topics));
    }

    @Override
    public void changeStateChanged(boolean isChecked, int id) {
        if (isChecked) {
            checkedSet.add(id);
        } else {
            checkedSet.remove(id);
        }
    }

    private class InterestAdapter extends BaseAdapter {

        @Override
        public int getCount() {
            return topics.size();
        }

        @Override
        public Topic getItem(int position) {
            return topics.get(position);
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            InterestCheckBox view = (InterestCheckBox) convertView;
            if (convertView == null) {
                view = new InterestCheckBox(getActivity(), parent);
            }
            view.setText(getItem(position).title);
            if (position % 2 == 1) {
                view.getVerticalDivider().setVisibility(View.GONE);
            }
            view.setTag(position);
            view.setListener(InterestsFragment.this);
            return view;
        }

        @Override
        public boolean isEnabled(int position) {
            return false;
        }
    }

    private class FriendsAdapter extends BaseAdapter {

        @Override
        public int getCount() {
            return mFriendsArray.length;
        }

        @Override
        public String getItem(int position) {
            return mFriendsArray[position];
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            InterestCheckBox view = (InterestCheckBox) convertView;
            if (convertView == null) {
                view = new InterestCheckBox(getActivity(), parent);
            }
            view.setText(getItem(position));
            if (position % 2 == 1) {
                view.getVerticalDivider().setVisibility(View.GONE);
            }
            return view;
        }

        @Override
        public boolean isEnabled(int position) {
            return false;
        }
    }

    private void getTopics() {
        String uid = Settings.getUid();
        String url = String.format(NetworkConstants.REGISTER_FAVORITE_URL, uid);
        AuthorizedJsonObjectRequest request = new AuthorizedJsonObjectRequest(
                Request.Method.GET, url,
                null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                LogUtils.d("getTopics, response is " + response);
                InterestsResponse resp = new Gson()
                        .fromJson(response.toString(), InterestsResponse.class);
                if (resp.ret) {
                    mListener.onSuccess(null);
                    topics.clear();
                    topics.addAll(Arrays.asList(resp.data));
                    mInterestAdapter.notifyDataSetChanged();
                } else {
                    mListener.onFailure(
                            response.optString("msg", getString(R.string.get_topics_failed)));
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                mListener.onFailure(getString(R.string.get_topics_failed));
            }
        });
        NetworkHelper.getInstance().getRequestQueue().add(request);
        NetworkHelper.getInstance().getRequestQueue().start();
        mListener.onShowProgress(getString(R.string.getting_topics));
    }

    private List<Topic> topics = new ArrayList<Topic>();

    private class InterestsResponse {

        boolean ret;

        Topic[] data;
    }

    private Set<Integer> checkedSet = new TreeSet<Integer>();

}
